#include <57header.h>

typedef struct conn_s{
    int net_fd;
    int alive; // 1存活， 0断开链接
    time_t lastTime; // 记录上一次说话的时间
}conn_t;

int main(int argc,char*argv[])
{
    char *port = "8080";
    char *ip = "192.168.106.129";

    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in sockaddr;
    sockaddr.sin_family = AF_INET;
    sockaddr.sin_port = htons(atoi(port));
    sockaddr.sin_addr.s_addr = inet_addr(ip);

    bind(socket_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
    listen(socket_fd,  20);
    
    conn_t list[1000];
    int size = 0;
    memset(list, 0, sizeof(list));

    fd_set set, temp;
    FD_ZERO(&set);
    FD_ZERO(&temp);

    FD_SET(socket_fd, &set);

    while(1){
        memcpy(&temp, &set, sizeof(set));

        struct timeval tv;
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        select(1000, &temp, NULL, NULL, &tv);
        if(FD_ISSET(socket_fd, &temp)){
            // 走到这说明有新的链接到来
            int net_fd = accept(socket_fd, NULL, NULL);
            list[size].alive = 1;
            list[size].net_fd = net_fd;
            time(&list[size].lastTime);
            size++;

            FD_SET(net_fd, &set);
        }

        for(int i=0; i<size; i++){
            if(list[i].alive==1 && FD_ISSET(list[i].net_fd, &temp)){
                // 下标为i的net——fd客户端， 发信息过来
                char buf[60] = {0};
                int ret = recv(list[i].net_fd, buf, sizeof(buf), 0);
                time(&list[i].lastTime);
                if(ret == 0){
                    // i这个客户端断开链接
                    list[i].alive = 0;
                    close(list[i].net_fd);
                    FD_CLR(list[i].net_fd, &set);
                    continue;
                }
                
                for(int j=0; j<size; j++){
                    if(list[j].alive==1 && i!=j){
                        send(list[j].net_fd, buf, sizeof(buf), 0);
                    }
                }
            }
        }

        // 判断是否超时
        time_t now_t;
        time(&now_t);
        for(int i=0; i<size; i++){
            if(list[i].alive==1 && now_t-list[i].lastTime>10){
                // 超时
                    list[i].alive = 0;
                    close(list[i].net_fd);
                    FD_CLR(list[i].net_fd, &set);
                
            }
        }

    }
    close(socket_fd);
    return 0;
}

